package drds.data_propagate.store;

import drds.data_propagate.common.LifeCycle;
import drds.data_propagate.entry.position.Position;

import java.util.List;
import java.util.concurrent.TimeUnit;

public interface EventStore<T> extends LifeCycle, StoreScavenge {

    /**
     * 添加一组数据对象，阻塞等待其操作完成 (比如一次性添加一个事务数据)
     */
    void put(List<T> data) throws InterruptedException, StoreException;

    /**
     * 添加一组数据对象，阻塞等待其操作完成或者时间超时 (比如一次性添加一个事务数据)
     */
    boolean put(List<T> data, long timeout, TimeUnit unit) throws InterruptedException, StoreException;

    /**
     * 添加一组数据对象 (比如一次性添加一个事务数据)
     */
    boolean tryPutOneTime(List<T> data) throws StoreException;

    /**
     * 添加一个数据对象，阻塞等待其操作完成
     */
    void put(T data) throws InterruptedException, StoreException;

    /**
     * 添加一个数据对象，阻塞等待其操作完成或者时间超时
     */
    boolean put(T data, long timeout, TimeUnit unit) throws InterruptedException, StoreException;

    /**
     * 添加一个数据对象
     */
    boolean tryPutOneTime(T data) throws StoreException;

    /**
     * 获取指定大小的数据，阻塞等待其操作完成
     */
    Events<T> get(Position start, int batchSize) throws InterruptedException, StoreException;

    /**
     * 获取指定大小的数据，阻塞等待其操作完成或者时间超时
     */
    Events<T> get(Position start, int batchSize, long timeout, TimeUnit unit)
            throws InterruptedException, StoreException;

    /**
     * 根据指定位置，获取一个指定大小的数据
     */
    Events<T> tryGet(Position start, int batchSize) throws StoreException;

    /**
     * 获取最后一条数据的position
     */
    Position getLatestBinLogEventPosition() throws StoreException;

    /**
     * 获取第一条数据的position，如果没有数据返回为null
     */
    Position getFirstBinLogEventPosition() throws StoreException;

    /**
     * 删除{@linkplain Position}之前的数据
     */
    void ack(Position position) throws StoreException;

    /**
     * 出错时执行回滚操作(未提交ack的所有状态信息重新归位，减少出错时数据全部重来的成本)
     */
    void rollback() throws StoreException;

}
